package FIT::TypeAdapter::Bool;

use FIT::Class;
use FIT::Document::Transformer;

extends 'FIT::TypeAdapter::Base';

# this is all so you get your actual results when Wrong in same
# style you wrote the expected
my @True_Values   = qw(T t Y y TRUE True true YES Yes yes 1 +);
my @False_Values  = qw(F f N n FALSE False false NO No no 0 -);
my %True_Values   = map { $_ => 1 } @True_Values;
my %False_Values  = map { $_ => 1 } @False_Values;
my %True_To_False = zip(\@True_Values, \@False_Values);
my %False_To_True = zip(\@False_Values, \@True_Values);
my %Opposites     = (%True_To_False, %False_To_True);

sub parse_from_string {
    my $text     = shift;
    my $is_true  = $True_Values{$text};
    my $is_false = $False_Values{$text};
    die "Can't adapt column [". $self->name. "], because [$text] is not Bool"
        if !$is_true && !$is_false;
    return $is_true? 1: 0;
}

sub compare {
    my ($actual, $expected) = @_;
    return $self->SUPER::compare($actual, $expected)
        if !defined($actual) || !defined($expected);
    $actual   = $actual  ? 1: 0;
    $expected = $expected? 1: 0;
    return $expected == $actual;
}

sub as_string {
    my ($actual, $expected, $result, $cell) = @_;
    if (!$cell)  { return $actual? 'true': 'false' }
    if ($result) { return $expected }
    return $Opposites{ $cell->fit_text };
}

sub zip() {
    local $_;
    my $max = -1;
    $max < $#$_ && ($max = $#$_) for @_;
    map { my $ix = $_; map $_->[$ix], @_; } 0..$max;
}

